<template>
  <tn-popup
    v-model="showPopup"
    mode="bottom"
    :safe-area-inset-bottom="false"
    :mask="mask"
    :z-index="zIndex"
    :content-custom-style="customPopupContentStyle"
    close-icon=""
    @close="handlePopupClose"
  >
    <view class="tn-select tn-safe-area-inset-bottom">
      <!-- 头部 -->
      <view class="tn-select__header">
        <!-- 取消按钮 -->
        <view
          class="cancel"
          :class="[cancelClass]"
          :style="cancelStyle"
          @tap.stop="handleCancelEvent"
        >{{ cancelText }}</view>
        <!-- 头部内容 -->
        <view class="content">
          <slot name="header"></slot>
        </view>
        <!-- 确认按钮 -->
        <view
          class="confirm"
          :class="[confirmClass]"
          :style="confirmStyle"
          @tap="handleConfirmEvent"
        >{{ confirmText }}</view>
      </view>

      <!-- select内容选择区 -->
      <view class="tn-select__content">
        <picker-view
          class="tn-select__picker-view"
          :value="selectValue"
          @change="handlePickerChange"
          @pickstart="handlePickerStart"
          @pickend="handlePickerEnd"
        >
          <picker-view-column
            v-for="(item, index) in columnData"
            :key="index"
            class="tn-select__picker-view-column"
          >
            <view
              v-for="(sub_item, sub_index) in item"
              :key="sub_index"
              class="tn-select__content__item"
            >
              <view class="tn-select__label tn-text-ellipsis-1">{{ sub_item[labelName] }}</view>
            </view>
          </picker-view-column>
        </picker-view>
      </view>
    </view>
  </tn-popup>
</template>

<script lang="ts" setup>
import { selectProps, selectEmits } from '../../../types/tn-select'
import { computed, CSSProperties, onMounted, ref, watch } from 'vue'
import { ColorInfo } from '../../../types/tuniao-ui'
import useComponentColor from '../../../libs/hooks/useComponentColor'
import { clone } from 'lodash-unified'
import { UPDATE_MODEL_EVENT } from '../../../constants'
import TnPopup from '../../tn-popup/src/Popup.vue'


const props = defineProps(selectProps)
const emits = defineEmits(selectEmits)

// 解析颜色
const { splitColorInfo } = useComponentColor()
// 解析取消文本颜色
const cancelColor = computed<ColorInfo>(() => {
  return splitColorInfo('color', props?.cancelColor)
})
// 解析确认文本颜色
const confirmColor = computed<ColorInfo>(() => {
  return splitColorInfo('color', props?.confirmColor)
})

// 取消按钮样式
const cancelStyle = computed<CSSProperties>(() => {
  let style: CSSProperties = {}
  if (cancelColor.value.type === 'style') style.color = cancelColor.value.value
  return style
})
// 确认按钮样式
const confirmStyle = computed<CSSProperties>(() => {
  let style: CSSProperties = {}
  if (confirmColor.value.type === 'style') style.color = confirmColor.value.value
  return style
})

// 取消按钮对应类
const cancelClass = computed<string>(() => {
  let clazz: string[] = []
  if (cancelColor.value.type === 'class') clazz.push(cancelColor.value.value)
  return clazz.join(' ')
})
// 确认按钮对应类
const confirmClass = computed<string>(() => {
  let clazz: string[] = []
  if (confirmColor.value.type === 'class') clazz.push(confirmColor.value.value)
  return clazz.join(' ')
})

// popup显示
let showPopup = ref<boolean>(false)
watch(() => props.modelValue, (val: boolean) => {
  showPopup.value = val
},{
  immediate: true
})
// popup自定义内容样式
const customPopupContentStyle = ref<CSSProperties>({
  backgroundColor: 'transparent'
})

// 用户列表数据
const data = computed<any[]>(() => {
  return props?.data || []
})
// value属性
const valueName = computed<string>(() => {
  return props?.valueName || 'value'
})
// label属性
const labelName = computed<string>(() => {
  return props?.labelName || 'label'
})
// children属性
const childrenName = computed<string>(() => {
  return props?.childName || 'children'
})
// 计算数据列数
const dataColumn = computed<number>(() => {
  // 单列只有一列
  if (props.mode === 'single') return 1
  // 多列计算数据列数
  if (props.mode === 'multi') return data.value.length
  // 关联多列计算第一项的children
  if (props.mode === 'autoMulti') {
    let count = 1
    let column: any[] = data.value
    while (column?.[0]?.[childrenName.value]) {
      column = column[0][childrenName.value] || []
      count++
    }
    return count
  }
  return 0
})
// 列表数据
const columnData = computed<any[]>(() => {
  // 单列模式下只有一列数据
  if (props.mode === 'single') return[data.value]
  if (props.mode === 'multi') return data.value
  if (props.mode === 'autoMulti') {
    // 根据选中后的index进行获取下一项
    let _columnData: any[] = Array(dataColumn.value).fill([])
    let currentColumnData: any[] = []
    let column: any[] = []
    for (let i = 0; i < dataColumn.value; i++) {
      if (i === 0) {
        currentColumnData = data.value || []
        column = currentColumnData?.[selectValue.value?.[i] || 0]?.[childrenName.value] || []
      } else {
        currentColumnData = column
        column = column?.[selectValue.value?.[i] || 0]?.[childrenName.value] || []
      }
      _columnData[i] = currentColumnData.map((item: any) => {
        return {
          [valueName.value]: item?.[valueName.value] || '',
          [labelName.value]: item?.[labelName.value] || ''
        }
      })
    }
    return _columnData
  }
  return []
})
// 标记是否正在滑动
let moving = ref<boolean>(true)
// 选中后对应的index
let selectValue = ref<number[]>([])
// 最近一次选中对应的index
let lastSelectValue = ref<number[]>([])

// 设置默认的选择的index
const initDefaultSelectValue = () => {
  // 如果没有设置默认值则用等长使用0填充的数组
  selectValue.value = props?.defaultValue && props.defaultValue.length === dataColumn.value ? props.defaultValue : Array(dataColumn.value).fill(0)
  lastSelectValue.value = clone(selectValue.value)
}
watch(() => {
  return [props.data, props.mode]
}, () => {
  console.log('update');
  initDefaultSelectValue()
})

// 开始滚动事件
const handlePickerStart = () => {
  // #ifdef MP-WEIXIN
  moving.value = true
  // #endif
}
// 结束滚动事件
const handlePickerEnd = () => {
  // #ifdef MP-WEIXIN
  moving.value = false
  // #endif
}
// 滚动选择事件
const handlePickerChange = (e: any) => {
  const value: number[] = e.detail.value

  // 单选/多选模式
  if (props.mode === 'single' || props.mode === 'multi') {
    selectValue.value = value
  }else if (props.mode === 'autoMulti') {
    // 判断修改的是哪一列
    const index = lastSelectValue.value.findIndex((val: number, i: number) => {
      return val !== value[i]
    })
    if (index === -1) return
    selectValue.value = value.map((val: number, i: number) => {
      return i <= index ? val : 0
    })
    lastSelectValue.value = selectValue.value
  }
}

// 取消事件
const handleCancelEvent = () => {
  emits('cancel')
  handlePopupClose()
}
// 确认事件
const handleConfirmEvent = () => {
  /* #ifdef MP-WEIXIN */
  // 正在滑动不返回
  if (moving.value) return
  /* #endif */
  // 获取选中项对应的值
  let _data: any[] = []
  if (props.mode === 'single') {
    const _value = data.value?.[selectValue.value[0]]?.[valueName.value]
    _data.push(_value !== undefined ? _value : '')
  } else if (props.mode === 'multi') {
    for(let i = 0; i < selectValue.value.length; i++) {
      const _value = data.value?.[i]?.[selectValue.value[i]]?.[valueName.value]
      _data.push(_value !== undefined ? _value : '')
    }
  }else if (props.mode === 'autoMulti') {
    let column: any[] = data.value
    for(let i = 0; i < selectValue.value.length; i++) {
      const _selectValue = selectValue.value[i]
      const _value = column?.[_selectValue]?.[valueName.value]
      _data.push(_value !== undefined ? _value : '')
      column = column?.[_selectValue][childrenName.value]
    }
  }
  emits('confirm', _data)
  handlePopupClose()
}

// popup关闭事件
const handlePopupClose = () => {
  emits(UPDATE_MODEL_EVENT, false)
}

onMounted(() => {
  initDefaultSelectValue()
})
</script>

<script lang="ts">
export default {
  options: {
    // 在微信小程序中将组件节点渲染为虚拟节点，更加接近Vue组件的表现(不会出现shadow节点下再去创建元素)
    virtualHost: true
  }
}
</script>

<style lang="scss" scoped>
@import '../../../theme.scss';

.tn-select {
  width: 100%;
  position: relative;
  background-color: #FFFFFF;
  border-radius: 20rpx 20rpx 0rpx 0rpx;

  &__header {
    width: 100%;
    display: flex;
    flex-direction: row;
    align-items: center;
    padding: 30rpx 20rpx;
    border-bottom: 1rpx solid #E6E6E6;

    .cancel,.confirm {
      width: 20%;
    }
    .cancel {
      padding-left: 20rpx;
      color: map-get(map-get($tn-type-color-map, 'danger'), 'normal');
    }
    .confirm {
      padding-right: 20rpx;
      text-align: right;
      color: map-get(map-get($tn-type-color-map, 'success'), 'normal');
    }
    .content {
      flex: 1;
      width: 100%;
      display: flex;
      align-items: center;
      justify-content: center;
    }
  }

  &__content {
    width: 100%;
    height: 500rpx;
    &__item {
      display: flex;
      flex-direction: row;
      align-items: center;
      justify-content: center;
    }
  }
  &__picker-view {
    height: 100%;
  }
  &__picker-view-column {
    width: 100%;
  }
}
</style>
